﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using XF.FM;

namespace XF.FM.Table
{
    public class TableRequest
    {
        const string orderIndex = "order[0][column]";
        const string dir = "order[0][dir]";

        public int Draw { get; set; }
        public int Start { get; set; }
        public int Length { get; set; }
        /// <summary>
        /// 视图模型属性排序名称，首字母默认小写
        /// </summary>
        public string OrderProp { get; set; }
        /// <summary>
        /// 升序/降序 true:asc  false:desc
        /// /// </summary>
        public bool IsAsc { get; set; }
        /// <summary>
        /// 解析Datatables的get请求order参数
        /// </summary>
        /// <param name="queryCollection"></param>
        public void ParseOrder(IQueryCollection queryCollection)
        {
            if (!queryCollection.ContainsKey(orderIndex))
                throw new ArgumentNullException("前端关闭了Table排序功能");
            if (int.TryParse(queryCollection[orderIndex].ToString(), out int _dataIndex))
            {
                OrderProp = queryCollection[$"columns[{_dataIndex}][data]"].ToString();
                if (queryCollection[dir].ToString() == "asc")
                    IsAsc = true;
                else
                    IsAsc = false;
            }
        }
        /// <summary>
        /// 解析Datatables的post请求order参数
        /// </summary>
        /// <param name="formCollection"></param>
        public void ParseOrder(IFormCollection formCollection)
        {
            if (!formCollection.ContainsKey(orderIndex))
                throw new ArgumentNullException("前端关闭了Table排序功能");
            if (int.TryParse(formCollection[orderIndex].ToString(), out int _dataIndex))
            {
                OrderProp = formCollection[$"columns[{_dataIndex}][data]"].ToString();
                if (formCollection[dir].ToString() == "asc")
                    IsAsc = true;
                else
                    IsAsc = false;
            }
        }



        /// <summary>
        /// 不需要过滤的数据
        /// </summary>
        /// <typeparam name="T">直接返回数据库实体模型</typeparam>
        /// <param name="quaryable">ef数据源</param>
        /// <returns></returns>
        public TableModel<T> GetEfResult<T>(IQueryable<T> quaryable) where T : class
        {
            TableModel<T> r = new TableModel<T>();
            r.Draw = Draw;
            r.RecordsTotal = quaryable.Count();
            r.RecordsFiltered = r.RecordsTotal;
            r.Data = quaryable.Skip(Start).Take(Length).ToList();
            return r;
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="quaryable"></param>
        /// <param name="isScend">true：升序</param>
        /// <param name="keySelector">属性/字段</param>
        /// <returns></returns>
        public TableModel<T> GetEfResult<T, TKey>(IQueryable<T> quaryable, bool isScend, Expression<Func<T, TKey>> keySelector)
        {
            TableModel<T> r = new TableModel<T>();
            r.Draw = Draw;
            r.RecordsTotal = quaryable.Count();
            r.RecordsFiltered = r.RecordsTotal;
            if (isScend)
                r.Data = quaryable.OrderBy(keySelector).Skip(Start).Take(Length).ToList();
            else
                r.Data = quaryable.OrderByDescending(keySelector).Skip(Start).Take(Length).ToList();
            return r;
        }
        /// <summary>
        /// 数据模型转换视图模型，先排序再调用这个
        /// </summary>
        /// <typeparam name="TOut">视图模型</typeparam>
        /// <typeparam name="TSource">数据实体</typeparam>
        /// <param name="sources"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public TableModel<TOut> GetEfResult<TSource, TOut>(IQueryable<TSource> sources,Expression<Func<TSource, TOut>> func) where TOut : class where TSource : class
        {
            TableModel<TOut> r = new TableModel<TOut>();
            r.Draw = Draw;
            r.RecordsTotal = sources.Count();
            r.RecordsFiltered = r.RecordsTotal;
            r.Data = sources.Select(func).OrderString(this.OrderProp,this.IsAsc).Skip(Start).Take(Length);
            return r;
        }
        /// <summary>
        /// 返回datatables数组结果，按顺序展示，不需要绑定，记得先对sources排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sources"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public TableModel<IList<string>> GetEfResult<T>(IQueryable<T> sources, Func<T, IList<string>> func)
        {
            TableModel<IList<string>> r = new TableModel<IList<string>>();
            r.Draw = Draw;
            r.RecordsTotal = sources.Count();
            r.RecordsFiltered = r.RecordsTotal;
            r.Data = sources.Skip(Start).Take(Length).Select(func);
            return r;
        }
    }
}
